LING: MIPS and POSIX ports Решил на майских поиграться с LING. Как оказалось это проще чем предполагалось. Как вы уже знаете LING может работать с недавнего времени на arm, xen_x86 и posix_x86. Чтобы скомпилировать LING на Mac OS X не нужно ничего кроме clang идущего с системой. $ git clone https://github.com/proger/ling & cd ling $ make ARCH=posix_x86 $ cd railing $ make ARCH=posix_x86 $ ./raling image $ ./raling.img Erlang [ling-0.3.2] Eshell V6.3 (abort with ^G) 1> LING идет вместе с railing — это штука типа rebar или mad, но которая может создавать только образы LING с vmling.o и встроенной файловой системой. По умолчанию LING включает только два приложения stdlib и kernel. И то без priv каталогов. Карта маунтов виртуальной файловой системы на 9p протоколе выглядит при этом так: 1> '9p_mounter':show_map(). -------------------------------------------------------------------- Prio | Point | Conn | Fid | Type -------------------------------------------------------------------- 11 | /boot | <0.25.0> | 0 | dir 12 | /erlang/lib/kernel-3.0.3/ebin | <0.25.0> | 1 | dir 13 | /erlang/lib/stdlib-2.2/ebin | <0.25.0> | 2 | dir -------------------------------------------------------------------- ok 1> ls("/boot"). local.map start.boot ok 2> io:format("~s~n",[binary_to_list(element(2,file:read_file("/boot/local.map")))]) . /boot /boot /erlang/lib/kernel-3.0.3/ebin /kernel /erlang/lib/stdlib-2.2/ebin /stdlib /erlang/lib/kvs/ebin /kvs /erlang/lib/db/ebin /db /erlang/lib/mad/ebin /mad /erlang/lib/sh/ebin /sh /erlang/lib/mnesia-4.12.3/ebin /mnesia Проблема в том, что в start.boot который берется из поставки Erlang/OTP умеет загружать только kernel и stdlib и чтобы писать загрузчик приложений во внутреннем формате Erlang/OTP нужнро самими генерировать эти структуры. Выглядит она вот так: 6> element(3,binary_to_term(element(2,file:read_file("/boot/start.boot")))). [{preLoaded, [erl_prim_loader,erlang,erts_internal,init,otp_ring0, prim_eval,prim_file,prim_inet,prim_zip,zlib]}, {progress,preloaded}, {path,["$ROOT/lib/kernel/ebin","$ROOT/lib/stdlib/ebin"]}, {primLoad,[error_handler]}, {kernel_load_completed}, {progress,kernel_load_completed}, {path,["$ROOT/lib/kernel/ebin"]}, {primLoad, [application,application_controller,application_master, application_starter,auth,code,code_server,disk_log, disk_log_1,disk_log_server,disk_log_sup,dist_ac,dist_util, erl_boot_server,erl_ddll,erl_distribution,erl_epmd, erl_reply,error_logger|...]}, {path,["$ROOT/lib/stdlib/ebin"]}, {primLoad, [array,base64,beam_lib,binary,c,calendar,dets,dets_server, dets_sup,dets_utils,dets_v8,dets_v9,dict,digraph, digraph_utils,edlin,edlin_expand|...]}, {progress,modules_loaded}, {path,["$ROOT/lib/kernel/ebin","$ROOT/lib/stdlib/ebin"]}, {kernelProcess,heart,{heart,start,[]}}, {kernelProcess,error_logger,{error_logger,start_link,[]}}, {kernelProcess,application_controller, {application_controller,start, [{application,kernel, [{description,"ERTS CXC 138 10"}, {vsn,[...]}, {id,...}, {...}|...]}]}}, {progress,init_kernel_started}, {apply, {application,load, [{application,stdlib, [{description,[...]},{vsn,...},{...}|...]}]}}, {progress,applications_loaded}, {apply,{application,start_boot,[kernel,permanent]}}, {apply,{application,start_boot,[stdlib,permanent]}}, {apply,{c,erlangrc,[]}}, {progress,started}] 7> [P||{path,[P]} <- element(3,binary_to_term(element(2,file:read_file("/boot/start.boot")))) ]. ["$ROOT/lib/kernel/ebin", "$ROOT/lib/stdlib/ebin"] Как видно здесь происходит вызов приложений, похоже мы можем просто вписывать операции запуска приложений как описанов в apply операциях: {apply,{application,start_boot,[kernel,permanent]}}, {apply,{application,start_boot,[stdlib,permanent]}}, {apply,{c,erlangrc,[]}}, Кстати здесь видно backdoor эрланговый, при запуске виртуальной машины BEAM, всегда вызывается c:erlangrc(). Я думаю что в LING это можно пофиксать, и не включать в start.boot этот вызов, а наоборот, вставить вызовы наших приложений. Чтобы заставить формировать файловую систему с проивольными приложениями, пришлось немного изменить railing, при этом я запустил основные свои приложения. 1> '9p_mounter':show_map(). -------------------------------------------------------------------- Prio | Point | Conn | Fid | Type -------------------------------------------------------------------- 11 | /boot | <0.25.0> | 0 | dir 12 | /erlang/lib/kernel-3.0.3/ebin | <0.25.0> | 1 | dir 13 | /erlang/lib/stdlib-2.2/ebin | <0.25.0> | 2 | dir 14 | /erlang/lib/kvs/ebin | <0.25.0> | 3 | dir 15 | /erlang/lib/db/ebin | <0.25.0> | 4 | dir 16 | /erlang/lib/mad/ebin | <0.25.0> | 5 | dir 17 | /erlang/lib/sh/ebin | <0.25.0> | 6 | dir 18 | /erlang/lib/mnesia-4.12.3/ebin | <0.25.0> | 7 | dir -------------------------------------------------------------------- 2> application:which_applications(). [{sh,"VXZ SH Executor","0.9"}, {mad,"MAD VXZ Build Tool","2.2"}, {db,"Bank Database","1"}, {kvs,"KVS Abstract Term Database","1"}, {mnesia,"MNESIA CXC 138 12","4.12.3"}, {stdlib,"ERTS CXC 138 10","2.2"}, {kernel,"ERTS CXC 138 10","3.0.3"}] 3> os:type(). {xen,ling} Пишет {xen,ling} но должно писать {posix,ling}. Пока буду заниматься формированием файловой системы для LING бандла. Итого mad в скором времени будет поддерживать два вида файлов: 1) это BEAM escript бандл со своей файловой системой которая распаковывается в ETS при запуске, и которая может затенятся локальными файлаим 2) Образ виртуальной машины LING слинкованый с файловой системой с erlang приложениями, при этом для posix порта, этот образ представляет собой исполняемый образ хост операционной системы. Что касается MIPS порта, то я только собрал mipsel-ling-elf-gcc-5.1.0 компилятор используя crosstool-ng, который используется при сборке ARM порта LING. Чтобы использовать один тулчейн для всех платформ, на MIPS тоже будем использовать crosstool-ng. Для этого надо создать в Disk Utility новый диск используя чувствительную к регистру журналируемую файловую систему. crosstool-ng имеет menuconfig В котором нужно выставить Little Endian для платы CI20 а также выставить tuple mipsel-ling-elf. Для создания raw U-Boot образов, проверить что статическая линковка отключена, и выбрать нужную libc: uLibc, musl, newlib. Поддержка libc у crosstool-ng просто шикарная. brew install crosstool-ng ct-ng mips-unknown-elf ct-ng menuconfig ct-ng build mipsel-ling-elf-gcc-5.1.0 --version mipsel-ling-elf-gcc-5.1.0 (crosstool-NG 1.20.0) 5.1.0 mipsel-ling-elf-objcopy --info ... elf32-littlemips elf32-bigmips elf64-bigmips elf64-littlemips mips elf32-littlemips elf32-bigmips elf64-bigmips elf64-littlemips plugin ---------------- ------------- ------------- ---------------- elf64-little elf64-big elf32-little elf32-big plugin srec mips elf64-little elf64-big elf32-little elf32-big ------ srec plugin elf64-little elf64-big elf32-little elf32-big ------ srec symbolsrec verilog tekhex binary ihex mips symbolsrec verilog tekhex binary ihex plugin symbolsrec verilog tekhex binary ihex gcc-5.1 прекрасно собирается clang, так что думаю можно еще xen_86 сборку перевести на crosstool-ng. Что касается драйвера последовтельного порта и startup.s, то придется понатыкивать с SDK примеров к CI20, тав вроде в arm ничего особенного, не думаю что с MIPS будут проблемы, божественная архитектура. Сейчас каталог arch в LING выглядит так: $ tree arch -L 1 arch ├── arm ├── mips ├── posix_x86 └── xen_x86